package com.chris.easymallproduct.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chris.common.constant.ProductConstant;
import com.chris.easymallproduct.dto.AttrGroupAddDto;
import com.chris.easymallproduct.dto.AttrGroupWithAttrsDto;
import com.chris.easymallproduct.dto.AttrRelationDto;
import com.chris.easymallproduct.entity.AttrAttrgroupRelationEntity;
import com.chris.easymallproduct.entity.AttrEntity;
import com.chris.easymallproduct.entity.CategoryEntity;
import com.chris.easymallproduct.service.*;
import com.chris.easymallproduct.vo.AttrGroupInfoVo;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chris.common.utils.PageUtils;
import com.chris.common.utils.Query;

import com.chris.easymallproduct.dao.AttrGroupDao;
import com.chris.easymallproduct.entity.AttrGroupEntity;


@Service("attrGroupService")
public class AttrGroupServiceImpl extends ServiceImpl<AttrGroupDao, AttrGroupEntity> implements AttrGroupService {

    @Autowired
    private AttrAttrgroupRelationService attrAttrgroupRelationService;
    @Autowired
    private CategoryBrandRelationService categoryBrandRelationService;
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private AttrService attrService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrGroupEntity> page = this.page(
                new Query<AttrGroupEntity>().getPage(params),
                new Query<AttrGroupEntity>().getPageWrapper(params, AttrGroupEntity.class)
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageById(Map<String, Object> params, Long id) {
        if (id == null || id == 0) {
            return queryPage(params);
        } else {
            IPage<AttrGroupEntity> page = this.page(
                    new Query<AttrGroupEntity>().getPage(params),
                    new Query<AttrGroupEntity>()
                            .getPageWrapper(params, AttrGroupEntity.class)
                            .lambda()
                            .eq(AttrGroupEntity::getCatelogId, id)
            );
            return new PageUtils(page);
        }
    }

    @Override
    public void save(AttrGroupAddDto attrGroup) {
        AttrGroupEntity attrGroupEntity = new AttrGroupEntity();
        BeanUtils.copyProperties(attrGroup, attrGroupEntity);
        this.save(attrGroupEntity);


    }

    @Override
    public AttrGroupInfoVo info(Long attrGroupId) {
        AttrGroupEntity attrGroupEntity = this.getById(attrGroupId);
        AttrGroupInfoVo attrGroupInfoVo = new AttrGroupInfoVo();
        if (attrGroupEntity != null) {
            BeanUtils.copyProperties(attrGroupEntity, attrGroupInfoVo);
            Long catelogId = attrGroupEntity.getCatelogId();
            List<Long> catelogPaths = new ArrayList<>();
            getCatelogPath(catelogId, catelogPaths);
            Collections.reverse(catelogPaths);
            attrGroupInfoVo.setCatelogPath(catelogPaths);
        }
        return attrGroupInfoVo;
    }

    @Override
    public void getCatelogPath(Long catelogId, List<Long> catelogPaths) {
        CategoryEntity categoryEntity = categoryService.getById(catelogId);
        if (categoryEntity != null) {
            catelogPaths.add(categoryEntity.getCatId());
            Long parentCid = categoryEntity.getParentCid();
            if (parentCid != 0) {
                getCatelogPath(categoryEntity.getParentCid(), catelogPaths);
            }
        }
    }

    @Override
    public List<AttrEntity> attrRelationInfo(Long id) {
        List<Long> attrs = attrAttrgroupRelationService.list(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .lambda()
                .eq(AttrAttrgroupRelationEntity::getAttrGroupId, id))
                .stream().map(AttrAttrgroupRelationEntity::getAttrId).collect(Collectors.toList());

        return attrs.size() == 0 ? new ArrayList<>() : attrService.list(new LambdaQueryWrapper<AttrEntity>()
                .in(AttrEntity::getAttrId, attrs));
    }

    @Override
    public void attrRelationDelete(AttrRelationDto[] deleteDtos) {
        List<AttrAttrgroupRelationEntity> entities = Arrays.stream(deleteDtos)
                .map(dto -> {
                    AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
                    attrAttrgroupRelationEntity.setAttrGroupId(dto.getAttrGroupId());
                    attrAttrgroupRelationEntity.setAttrId(dto.getAttrId());
                    return attrAttrgroupRelationEntity;
                }).collect(Collectors.toList());
        baseMapper.attrRelationDelete(entities);

    }

    @Override
    public PageUtils noattrRelation(Map<String, Object> params, Long id) {
        AttrGroupEntity attrGroupEntity = this.getById(id);
        Long catelogId = attrGroupEntity.getCatelogId();
        List<Long> groupList = this.list(new LambdaQueryWrapper<AttrGroupEntity>()
                .eq(AttrGroupEntity::getCatelogId, catelogId))
                .stream()
                .map(AttrGroupEntity::getAttrGroupId)
                .collect(Collectors.toList());

        List<Long> attrs = attrAttrgroupRelationService.list(new QueryWrapper<AttrAttrgroupRelationEntity>()
                .lambda()
                .in(AttrAttrgroupRelationEntity::getAttrGroupId, groupList))
                .stream()
                .map(AttrAttrgroupRelationEntity::getAttrId)
                .collect(Collectors.toList());
        IPage<AttrEntity> page = new Page<>();
        if (attrs.size() > 0) {
            page = attrService.page(
                    new Query<AttrEntity>().getPage(params),
                    new Query<AttrEntity>()
                            .getPageWrapper(params, AttrEntity.class)
                            .lambda()
                            .eq(AttrEntity::getCatelogId, catelogId)
                            .notIn(AttrEntity::getAttrId, attrs)
                            .eq(AttrEntity::getAttrType, ProductConstant.AttrTypeEnum.BASE.getCode()));
        }
        return new PageUtils(page);
    }

    @Override
    public void attrRelation(AttrRelationDto[] deleteDtos) {
        List<AttrAttrgroupRelationEntity> entities = Arrays.stream(deleteDtos)
                .map(dto -> {
                    AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();
                    attrAttrgroupRelationEntity.setAttrGroupId(dto.getAttrGroupId());
                    attrAttrgroupRelationEntity.setAttrId(dto.getAttrId());
                    return attrAttrgroupRelationEntity;
                }).collect(Collectors.toList());
        attrAttrgroupRelationService.saveBatch(entities);
    }

    @Override
    public List<AttrGroupWithAttrsDto> attrGroupWithAttrs(Long catelogId) {
        return this.list(new LambdaQueryWrapper<AttrGroupEntity>()
                .eq(AttrGroupEntity::getCatelogId, catelogId))
                .stream()
                .map(attrGroupEntity -> {
                    AttrGroupWithAttrsDto dto = new AttrGroupWithAttrsDto();
                    BeanUtils.copyProperties(attrGroupEntity, dto);
                    dto.setAttrs(attrRelationInfo(dto.getAttrGroupId()));
                    return dto;
                }).collect(Collectors.toList());
    }

}